#pragma once

namespace gecko
{

	namespace gtl
	{

		// forward declarations
		namespace internal { template<typename T> class DefaultVectorBlockAllocator; }
		namespace internal { template<typename T> class VectorIterator; }

		// simple vector class for dynamic contiguous array
		template<typename T, typename ALLOCATOR = internal::DefaultVectorBlockAllocator<T>>
		class Vector
		{
		public:
			// iterator types
			typedef internal::VectorIterator<T> Iterator;
			typedef internal::VectorIterator<const T> ConstIterator;

			// construct a vector
			Vector();

			// destructor
			~Vector();

			// reserve some contiguous memory
			void Reserve(size_t size);

			// push an item onto the back of the vector
			void PushBack(const T& item);

			// remove an item
			T& PopBack();

			// remove an item
			const T& PopBack() const;

			// get the iterator corresponding to the start of the buffer
			Iterator Begin();

			// get the iterator corresponding to the end of the buffer
			Iterator End();

			// get the iterator corresponding to the start of the buffer
			ConstIterator Begin() const;

			// get the iterator corresponding to the end of the buffer
			ConstIterator End() const;

			// destroy the buffer
			void Clear();

			// Find an item in the list (searches linearly O(n))
			Iterator Find(const T& data);

			// Find an item in the list (searches linearly O(n)) - const version
			ConstIterator Find(const T& data) const;

			// Get the number of items in the list
			unsigned int Size();

			// Test if the list is empty
			bool Empty();

			// Get the item on the front of the list
			T& Front();

			// Get the item on the front of the list (const version)
			const T& Front() const;

			// Get the item on the back of the list
			T& Back();

			// Get the item on the back of the list (const version)
			const T& Back() const;

		private:
			// the memory buffer
			T* m_buffer;

			// number of items
			size_t m_size;

			// overall capacity of the vector
			size_t m_capacity;
		};

	} // namespace gtl

} // namespace gecko

#include "vector.inl"